﻿namespace Ngs.Extensions
{
    using System;
    using System.Globalization;
    using System.Security.Cryptography;
    using System.Text.RegularExpressions;
    using System.Text;

    public static class StringExtensions
    {
        private static readonly Regex WebUrlExpression = new Regex(@"(http|https)://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?", RegexOptions.Singleline | RegexOptions.Compiled);
        private static readonly Regex EmailExpression = new Regex(@"^([0-9a-zA-Z]+[-._+&])*[0-9a-zA-Z]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$", RegexOptions.Singleline | RegexOptions.Compiled);
        private static readonly Regex StripHTMLExpression = new Regex("<\\S[^><]*>", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.CultureInvariant | RegexOptions.Compiled);

        private static readonly char[] IllegalUrlCharacters = new[] { ';', '/', '\\', '?', ':', '@', '&', '=', '+', '$', ',', '<', '>', '#', '%', '.', '!', '*', '\'', '"', '(', ')', '[', ']', '{', '}', '|', '^', '`', '~', '–', '‘', '’', '“', '”', '»', '«' };

        static StringExtensions()
        {
        }

        public static string ProperCase(this string s)
        {
            s = s.ToLower();
            string proper = string.Empty;

            foreach (string ss in s.Split(StringConstants.Space))
            {
                proper += char.ToUpper(ss[0]);
                proper += (ss.Substring(1, ss.Length - 1) + StringConstants.Space);
            }
            return proper;
        }

        public static string FormatWith(this string target, params object[] args)
        {
            ExceptionFactory.ThrowIfArgumentNullOrEmpty(target, "target");

            return string.Format(CultureInfo.CurrentCulture, target, args);
        }

        public static bool IsWebUrl(this string target)
        {
            return !string.IsNullOrEmpty(target) && WebUrlExpression.IsMatch(target);
        }

        public static bool IsEmail(this string target)
        {
            return !string.IsNullOrEmpty(target) && EmailExpression.IsMatch(target);
        }

        #region Hashing

        public static string Hash(this string target)
        {
            using (HashAlgorithm algo = HashAlgorithm.Create())
            {
                return Hash(target, algo);
            }
        }

        public static string Hash(this string target, string algoName)
        {
            using (HashAlgorithm algo = HashAlgorithm.Create(algoName))
            {
                return Hash(target, algo);
            }
        }

        public static string Hash(this string target, HashAlgorithm algo)
        {
            ExceptionFactory.ThrowIfArgumentNull(algo);
            byte[] data = Encoding.Unicode.GetBytes(target);
            byte[] hash = algo.ComputeHash(data);

            return Convert.ToBase64String(hash);
        }
        #endregion
    }
}
